home *** CD-ROM | disk | FTP | other *** search
/ Linux Programs 1995 Summer / Linux Programs.iso / ghostscr / gs261dif.tgz / gs261dif.tar / gdevlinux.c next >
C/C++ Source or Header  |  1994-08-07  |  16KB  |  465 lines

  1. /* Copyright (C) 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /*
  21.  * gdevlinux.c
  22.  *
  23.  * This is a driver for 386 PCs using VGALIB for graphics on the console 
  24.  * display.
  25.  *
  26.  * Written by Sigfrid Lundberg, siglun@euler.teorekol.lu.se.
  27.  *
  28.  * Support for all the SVGAlib video modes, MAGSTEP, XO, YO, and additions
  29.  * to the gs.1 man page by Patrick Volkerding, volkerdi@mhd1.moorhead.msus.edu.
  30.  *
  31.  * Modified by Minh Phanivong, minh@kbs.citri.edu.au
  32.  *
  33.  * 5/8/94
  34.  * - improved performance using the vgagl library
  35.  * - mode is now hardcoded to G1024x786x265 (12)
  36.  * - Makefile changed to include -lvgagl
  37.  *
  38.  */
  39.  
  40. #include "gx.h"
  41. #include "gxdevice.h"
  42. #include "gserrors.h"
  43.  
  44. #include <errno.h>
  45. #include <vga.h>
  46. #include <vgagl.h>
  47.  
  48. extern char svgalib_detected;
  49. extern char video_resolution[25];
  50. extern float size_multiplier; 
  51. extern float adjust_xo;
  52. extern float adjust_yo;
  53. extern char xo_units;
  54. extern char yo_units;
  55.  
  56. GraphicsContext physicalscreen;
  57.  
  58. int screen_width, screen_height;
  59. int xorigin, yorigin;
  60.  
  61. typedef struct gx_device_linux {
  62.     gx_device_common;
  63.     int fd;                    /* window file descriptor */
  64.     uchar *screen;             /* pointer to screen image */
  65.     ushort line_size;          /* size of single screen line in bytes */
  66.     ulong screen_size;         /* size of screen image in bytes */
  67.     int screen_width, screen_height; /* size of screen used */
  68.     int page;                  /* page number */
  69. #ifdef LINUX_PERF
  70.     char *no_output, *no_fill, *no_copy;
  71. #endif
  72. } gx_device_linux;
  73. #define linuxdev ((gx_device_linux *)dev)
  74.  
  75. #define XDPI   60              /* to get a more-or-less square aspect ratio */
  76. #define YDPI   60
  77.  
  78. #ifndef A4 /*Letter size*/
  79. #define YSIZE (20.0 * YDPI / 2.5))
  80. #define XSIZE (8.5 / 11)*YSIZE /* 8.5 x 11 inch page, by default */
  81. #else  /* A4 paper */
  82. #define XSIZE 8.27
  83. #define YSIZE 11.69 
  84. #endif
  85.  
  86. dev_proc_open_device(linux_open);
  87. dev_proc_close_device(linux_close);
  88. dev_proc_draw_line(linux_draw_line);
  89. dev_proc_fill_rectangle(linux_fill_rectangle);
  90. dev_proc_tile_rectangle(linux_tile_rectangle);
  91. dev_proc_map_color_rgb(linux_map_color_rgb);
  92. dev_proc_map_rgb_color(linux_map_rgb_color);
  93. dev_proc_copy_mono(linux_copy_mono);
  94. dev_proc_copy_color(linux_copy_color);
  95.  
  96.  
  97.  
  98. private gx_device_procs linux_procs = {
  99.     linux_open,
  100.     gx_default_get_initial_matrix,
  101.     gx_default_sync_output,
  102.     gx_default_output_page,
  103.     linux_close,
  104.     linux_map_rgb_color,
  105.     linux_map_color_rgb,
  106.     linux_fill_rectangle,
  107.     linux_tile_rectangle,
  108.     linux_copy_mono,
  109.     linux_copy_color,
  110.     linux_draw_line,
  111.     gx_default_get_bits,
  112.     gx_default_get_props,
  113.     gx_default_put_props
  114. };
  115.  
  116. gx_device_linux gs_linux_device = {
  117.     sizeof(gx_device_linux),
  118.     &linux_procs,
  119.     "linux",
  120.     0,0,
  121.     1,1,
  122.     no_margins,
  123.     dci_black_and_white,
  124.     0
  125. };
  126.  
  127. int
  128. linux_open(gx_device *dev)
  129. {
  130.   vga_init();
  131. /*
  132.   if (!strcmp(video_resolution,"320x200x16") || !strcmp(video_resolution,"1")) {
  133.     vga_setmode(1);
  134.   } else if (!strcmp(video_resolution,"640x200x16") || !strcmp(video_resolution,"2")) {
  135.     vga_setmode(2);
  136.   } else if (!strcmp(video_resolution,"640x350x16") || !strcmp(video_resolution,"3")) {
  137.     vga_setmode(3);
  138.   } else if (!strcmp(video_resolution,"640x480x16") || !strcmp(video_resolution,"4")) {
  139.     vga_setmode(4);
  140.   } else if (!strcmp(video_resolution,"320x200x256") || !strcmp(video_resolution,"5")) {
  141.     vga_setmode(5);
  142.   } else if (!strcmp(video_resolution,"320x240x256") || !strcmp(video_resolution,"6")) {
  143.     vga_setmode(6);
  144.   } else if (!strcmp(video_resolution,"320x400x256") || !strcmp(video_resolution,"7")) {
  145.     vga_setmode(7);
  146.   } else if (!strcmp(video_resolution,"360x480x256") || !strcmp(video_resolution,"8")) {
  147.     vga_setmode(8);
  148.   } else if (!strcmp(video_resolution,"640x480x2") || !strcmp(video_resolution,"9")) {
  149.     vga_setmode(9);
  150.   } else if (!strcmp(video_resolution,"640x480x256") || !strcmp(video_resolution,"10")) {
  151.     vga_setmode(10);
  152.   } else if (!strcmp(video_resolution,"800x600x256") || !strcmp(video_resolution, "11")) {
  153.     vga_setmode(11);
  154.   } else if (!strcmp(video_resolution,"1024x768x256") || !strcmp(video_resolution,"12")) {
  155.     vga_setmode(12);
  156.   } else if (!strcmp(video_resolution,"320x200x32K") || !strcmp(video_resolution,"13")) {
  157.     vga_setmode(13);
  158.   } else if (!strcmp(video_resolution,"320x200x64K") || !strcmp(video_resolution,"14")) {
  159.     vga_setmode(14);
  160.   } else if (!strcmp(video_resolution,"320x200x16M") || !strcmp(video_resolution,"15")) {
  161.     vga_setmode(15);
  162.   } else if (!strcmp(video_resolution,"640x480x32K") || !strcmp(video_resolution,"16")) {
  163.     vga_setmode(16);
  164.   } else if (!strcmp(video_resolution,"640x480x64K") || !strcmp(video_resolution,"17")) {
  165.     vga_setmode(17);
  166.   } else if (!strcmp(video_resolution,"640x480x16M") || !strcmp(video_resolution,"18")) {
  167.     vga_setmode(18);
  168.   } else if (!strcmp(video_resolution,"800x600x32K") || !strcmp(video_resolution,"19")) {
  169.     vga_setmode(19);
  170.   } else if (!strcmp(video_resolution,"800x600x64K") || !strcmp(video_resolution,"20")) {
  171.     vga_setmode(20);
  172.   } else if (!strcmp(video_resolution,"800x600x16M") || !strcmp(video_resolution,"21")) {
  173.     vga_setmode(21);
  174.   } else if (!strcmp(video_resolution,"1024x768x32K") || !strcmp(video_resolution,"22")) {
  175.     vga_setmode(22);
  176.   } else if (!strcmp(video_resolution,"1024x768x64K") || !strcmp(video_resolution,"23")) {
  177.     vga_setmode(23);
  178.   } else if (!strcmp(video_resolution,"1024x768x16M") || !strcmp(video_resolution,"24")) {
  179.     vga_setmode(24);
  180.   } else if (!strcmp(video_resolution,"1280x1024x256") || !strcmp(video_resolution,"25")) {
  181.     vga_setmode(25);
  182.   } else if (!strcmp(video_resolution,"1280x1024x32K") || !strcmp(video_resolution,"26")) {
  183.     vga_setmode(26);
  184.   } else if (!strcmp(video_resolution,"1280x1024x64K") || !strcmp(video_resolution,"27")) {
  185.     vga_setmode(27);
  186.   } else if (!strcmp(video_resolution,"1280x1024x16M") || !strcmp(video_resolution,"28")) {
  187.     vga_setmode(28);
  188.   } else if (!strcmp(video_resolution,"720x350x16") || !strcmp(video_resolution,"29")) {
  189.     vga_setmode(29);
  190.   } else if (!strcmp(video_resolution,"720x480x16") || !strcmp(video_resolution,"30")) {
  191.     vga_setmode(30);
  192.   } else {
  193.     fprintf(stdout,"Sorry, but %s is not a recognized SVGAlib mode.\n\n",video_resolution);
  194.     fprintf(stdout,"These are the recognized video modes, (and mode numbers):\n");
  195.     fprintf(stdout," 320x200x16 (1), 640x200x16 (2), 640x350x16 (3), 640x480x16 (4), \n");
  196.     fprintf(stdout," 320x200x256 (5), 320x240x256 (6), 320x400x256 (7), 360x480x256 (8), \n");
  197.     fprintf(stdout," 640x480x2 (9), 640x480x256 (10), 800x600x256 (11), 1024x768x256 (12), \n");
  198.     fprintf(stdout," 320x200x32K (13), 320x200x64K (14), 320x200x16M (15), 640x480x32K (16), \n");
  199.     fprintf(stdout," 640x480x64K (17), 640x480x16M (18), 800x600x32K (19), 800x600x64K (20), \n");
  200.     fprintf(stdout," 800x600x16M (21), 1024x768x32K (22), 1024x768x64K (23), 1024x768x16M (24), \n");
  201.     fprintf(stdout," 1280x1024x256 (25), 1280x1024x32K (26), 1280x1024x64K (27), \n");
  202.     fprintf(stdout," 1280x1024x16M (28), 720x350x16 (29), 720x480x16 (30), \n");
  203.     fprintf(stdout,"\n");
  204.     fprintf(stdout,"In addition to -r<resolution>, these flags also work with -sDEVICE=linux:\n");
  205.     fprintf(stdout,"\n");
  206.     fprintf(stdout,"  -dMAGSTEP=<value> : Change the image size. Values 0.0 < value < 1.0 shrink\n");
  207.     fprintf(stdout,"       the image size, while values > 1.0 expand it. The default value is 1.0.\n");
  208.     fprintf(stdout,"\n");
  209.     fprintf(stdout,"  -dXO=<value>[units], -dYO=<value>[units] : Specify a new origin. The upper-\n");
  210.     fprintf(stdout,"       left hand corner of the image is considered to be (0,0). You may move\n");
  211.     fprintf(stdout,"       the origin down and/or right using these flags. The default unit of \n");
  212.     fprintf(stdout,"       measurement is inches (in), but you may also use centimeters (cm), or\n");
  213.     fprintf(stdout,"       percent (%%) of distance from the origin (0%% - 100%%).\n");
  214.     exit(1);
  215.   }
  216.   fprintf(stdout,"\nSelected SVGAlib resolution: %s\n",video_resolution);
  217. */
  218.     vga_setmode(12);
  219.   gl_setcontextvga(12);
  220.   gl_getcontext(&physicalscreen);
  221.   gl_clearscreen(1);
  222.  
  223.   if ( dev->width == 0 )
  224.     dev->width = vga_getxdim() * size_multiplier; /* + 1; */
  225.     screen_width = vga_getxdim();
  226.   if ( dev->height == 0 )
  227.     dev->height = vga_getydim() * size_multiplier; /* + 1; */
  228.     screen_height = vga_getydim();
  229.  
  230.   /*vgalib provides no facilities for finding out aspect ratios*/
  231.   if ( dev->y_pixels_per_inch == 1 ) {
  232.     dev->y_pixels_per_inch = dev->height / 11.0;
  233.     dev->x_pixels_per_inch = dev->y_pixels_per_inch;
  234.     if (xo_units == 'c') adjust_xo /= 2.58;
  235.     if (yo_units == 'c') adjust_yo /= 2.58;
  236.     if (xo_units == '%') {
  237.       if (adjust_xo < 0) adjust_xo = 0;
  238.       if (adjust_xo > 100) adjust_xo = 100;
  239.       adjust_xo = 8.5 * (adjust_xo/100);
  240.     }
  241.     if (yo_units == '%') {
  242.       if (adjust_yo < 0) adjust_yo = 0;
  243.       if (adjust_yo > 100) adjust_yo = 100;
  244.       adjust_yo = 11 * (adjust_yo/100);
  245.     }
  246.     xorigin = dev->x_pixels_per_inch * adjust_xo;
  247.     yorigin = dev->y_pixels_per_inch * adjust_yo;
  248.   }
  249.  
  250.   /* Find out if the device supports color */
  251.   /* (default initialization is monochrome). */
  252.   /* We only recognize 16-color devices right now. */
  253.   if ( vga_getcolors() > 1 ) {
  254.    
  255.     int index,one,rgb[3];
  256.  
  257.     static gx_device_color_info linux_16color = dci_color(4, 2, 3);
  258.     dev->color_info = linux_16color;  
  259.  
  260.     for(index=0;index<gx_max_color_value;index++) {
  261.       one = (index & 8 ? gx_max_color_value : gx_max_color_value / 3);
  262.       rgb[0] = (index & 4 ? one : 0);
  263.       rgb[1] = (index & 2 ? one : 0);
  264.       rgb[2] = (index & 1 ? one : 0);
  265.       vga_setpalette((int)index, rgb[0], rgb[1], rgb[2]);
  266.     }
  267.   }
  268.  
  269.   return 0;
  270. }
  271.  
  272. int
  273. linux_close(gx_device *dev)
  274. {
  275.   vga_getch();
  276.   vga_setmode(TEXT);
  277.   return 0;
  278. }
  279.  
  280. gx_color_index
  281. linux_map_rgb_color(gx_device *dev, gx_color_value red, gx_color_value green,
  282.                    gx_color_value blue)
  283. {
  284.   int index;
  285.  
  286.   index=((red > gx_max_color_value / 4 ? 4 : 0) +
  287.         (green > gx_max_color_value / 4 ? 2 : 0) +
  288.         (blue > gx_max_color_value / 4 ? 1 : 0) +
  289.         (red > gx_max_color_value / 4 * 3 ||
  290.          green > gx_max_color_value / 4 * 3 ? 8 : 0));
  291.  
  292.   return (gx_color_index)index;
  293. }
  294.  
  295.  
  296. /* I actually don't understand what I'm doing -- the only thing I want to
  297. achieve are palettes that emulates BGI */
  298. int
  299. linux_map_color_rgb(gx_device *dev, gx_color_index index, 
  300.                    unsigned short rgb[3])
  301. {  
  302.   int red, green, blue;
  303.   gx_color_value one = 
  304.     (index & 8 ? gx_max_color_value : gx_max_color_value / 3);
  305.   rgb[0] = (index & 4 ? one : 0);
  306.   rgb[1] = (index & 2 ? one : 0);
  307.   rgb[2] = (index & 1 ? one : 0);
  308.  
  309.   return 0;
  310. }
  311.  
  312. void
  313. adj_vga_drawpixel(int x, int y, int c)
  314. {
  315.   y -= yorigin;
  316.   x -= xorigin;
  317.   if (x < 0 || x >= screen_width || y < 0 || y >= screen_height) return;
  318.   gl_setpixel(x,y,c);
  319. }
  320.  
  321. void
  322. adj_vga_drawline(int x1, int y1, int x2, int y2, int c)
  323. {
  324.   y1 -= yorigin;
  325.   y2 -= yorigin;
  326.   x1 -= xorigin;
  327.   x2 -= xorigin;
  328.   if (x1 < 0 || x1 >= screen_width || y1 < 0 || y1 >= screen_height) return;
  329.   if (x2 < 0 || x2 >= screen_width || y2 < 0 || y2 >= screen_height) return;
  330.   gl_line(x1,y1,x2,y2,c);
  331. }
  332.  
  333. int
  334. linux_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, 
  335.                gx_color_index color)
  336. {  
  337.   if(!((x0==x1)&&(y0==y1))) {
  338.     adj_vga_drawline(x0,y0,x1,y1,color);
  339.   }
  340.   return 0;
  341. }
  342.  
  343. int
  344. linux_tile_rectangle(gx_device *dev, const gx_bitmap *tile,
  345.   int x, int y, int w, int h, gx_color_index czero, gx_color_index cone,
  346.   int px, int py)
  347. {
  348.   if ( czero != gx_no_color_index && cone != gx_no_color_index ) {
  349.     linux_fill_rectangle(dev, x, y, w, h, czero);
  350.     czero = gx_no_color_index;
  351.   }
  352.   return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px, py);
  353. }
  354.  
  355.  
  356. int
  357. linux_fill_rectangle(gx_device *dev, int x, int y, int w, int h,
  358.                       gx_color_index color)
  359. {
  360.   int i,j;
  361.   fit_fill(dev, x, y, w, h);
  362.   gl_fillbox(x, y, w, h, color);
  363.   return 0;
  364. }
  365.  
  366. int
  367. linux_copy_mono(gx_device *dev,
  368.   const byte *base, int sourcex, int raster, gx_bitmap_id id,
  369.   int x, int y, int width, int height,
  370.   gx_color_index zero, gx_color_index one)
  371.  
  372. {
  373.   const byte *ptr_line = base + (sourcex >> 3);
  374.   int left_bit = 0x80 >> (sourcex & 7);
  375.   int dest_y = y, end_x = x + width;
  376.   int invert = 0;
  377.   int color;
  378.   int i;
  379.  
  380.   fit_copy(dev, base, sourcex, raster, id, x, y, width, height);
  381.  
  382.   if ( zero == gx_no_color_index ) {
  383.     if ( one == gx_no_color_index ) return 0;
  384.     color = (int)one;
  385.   } else {
  386.     if ( one == gx_no_color_index ) {
  387.       color = (int)zero;
  388.       invert = -1;
  389.     } else {   /* Pre-clear the rectangle to zero */
  390.       linux_fill_rectangle(dev,x,y,width,height,zero);
  391.       color = (int)one;
  392.     }
  393.   }
  394.  
  395.   
  396.   while( height-- ) { /* for each line */ 
  397.     const byte *ptr_source = ptr_line;
  398.     register int dest_x = x;
  399.     register int bit = left_bit;
  400.     while ( dest_x < end_x ) { /* for each bit in the line */
  401.       if ( (*ptr_source ^ invert)  & bit ) 
  402.       adj_vga_drawpixel(dest_x,dest_y,color);
  403.       dest_x++;
  404.       if ( (bit >>= 1) == 0 )
  405.        bit = 0x80, ptr_source++;
  406.     }
  407.     dest_y++;
  408.     ptr_line += raster;
  409.   }  
  410.   return 0;
  411. }
  412.  
  413.  
  414. /* Copy a color pixel map.  This is just like a bitmap, except that */
  415. /* each pixel takes 4 bits instead of 1 when device driver has color. */
  416. int
  417. linux_copy_color(gx_device *dev,
  418.   const byte *base, int sourcex, int raster, gx_bitmap_id id,
  419.   int x, int y, int width, int height)
  420. {
  421.  
  422.   fit_copy(dev, base, sourcex, raster, id, x, y, width, height);
  423.  
  424.   if ( gx_device_has_color(dev) ) { /* color device, four bits per pixel */
  425.     const byte *line = base + (sourcex >> 1);
  426.     int dest_y = y, end_x = x + width, i;
  427.  
  428.     if ( width <= 0 ) return 0;
  429.     while ( height-- )  { /* for each line */
  430.       const byte *source = line;
  431.       register int dest_x = x;
  432.       if ( sourcex & 1 ) {    /* odd nibble first */
  433.        int color =  *source++ & 0xf;
  434.        adj_vga_drawpixel(dest_x,dest_y,color);
  435.        dest_x++;
  436.       }
  437.       /* Now do full bytes */
  438.       while ( dest_x < end_x ) {
  439.        int color = *source >> 4;
  440.        adj_vga_drawpixel(dest_x,dest_y,color);
  441.        dest_x++;
  442.        if ( dest_x < end_x ) {
  443.          color =  *source++ & 0xf;
  444.          adj_vga_drawpixel(dest_x,dest_y,color);
  445.          dest_x++;
  446.        }
  447.       }
  448.       dest_y++;
  449.       line += raster;
  450.     }
  451.   } else { /* monochrome device: one bit per pixel */
  452.     /* bitmap is the same as bgi_copy_mono: one bit per pixel */
  453.     linux_copy_mono(dev, base, sourcex, raster, id, x, y, width, height,
  454.                  (gx_color_index)0, (gx_color_index)7);
  455.     }
  456.   return 0;
  457. }
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.